By
    
      yusijia
    
  
    
    Updated:
    
  
	
		
		
		
		
		题目:
http://poj.org/problem?id=2299
注意: 树状数组下标要从1开始
分析:
例如 :
pos:1 2 3 4 5
val: 9 1 0 5 4
离散化:
  将上面的val变为5 2 1 4 3   离散后的数据
         输入的顺序为1 2 3 4 5   reflect数组的下标
sort(node + 1, node + 1 + n, cmp);
       val:  0 1 4 5 9
       pos:  3 2 5 4 1
val离散成下标1 2 3 4 5
就成了:1的输入顺序是3,2的输入顺序是2,3的输入顺序是5,4的输入顺序是4,5的输入顺序是1
reflect[node[i].pos] = i;
   reflect下标: 1 2 3 4 5
离散后的数据:5 2 1 4 3 (按输入的顺序)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
   | 
  #include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace std;
  const int N = 500005;
  struct Node{     int val;				     int pos;				 };
  Node node[N]; int n; int tree[N], reflect[N];		
  bool cmp(const Node &a, const Node &b) {     return a.val < b.val; }
  int lowbit(int x) {     return x & -x; }
  void update(int index, int val) {     while(index <= n){         tree[index] += val;         index += lowbit(index);     } }
  int getsum(int index) {     int sum = 0;     while(index > 0){         sum += tree[index];         index -= lowbit(index);     }     return sum; }
  int main() {     while(scanf("%d", &n) != EOF && n){         for(int i = 1; i <= n; i++){             scanf("%d", &node[i].val);             node[i].pos = i;         }         sort(node + 1, node + 1 + n, cmp);         for(int i = 1; i <= n; i++){             reflect[node[i].pos] = i;	           }         for(int i = 1; i <= n; i++)             tree[i] = 0;         long long ans = 0;         for(int i = 1; i <= n; i++){             update(reflect[i], 1);             ans += i - getsum(reflect[i]);          }         printf("%lld\n", ans);     }     return 0; }
 
  |